package cc.telecomdigital.tdstock.trading.Services;

import java.io.IOException;

import cc.telecomdigital.tdstock.R;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import cc.telecomdigital.tdstock.Framework.UniqueItem.DeviceInfo;
import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;
import cc.telecomdigital.tdstock.Services.CommunicTools;

import cc.telecomdigital.tdstock.trading.Common.Trade_AppConstant;
import cc.telecomdigital.tdstock.trading.Common.Trade_StockViewInfoItem;
import cc.telecomdigital.tdstock.trading.Tools.Trade_StockFunctionTools;

import android.content.Context;
import android.os.Handler;
import android.os.Message;

public class TradeGetDetailStockQuote
{
	protected final String	LOG_TAG	= "TradeGetStockDetailQuote";

	// Call back interface
	public interface ITradeGetStockQuoteResponse
	{
		/** if iSuccessfulSend == false, it means the there is a communication error
		    do not consider the iReponse as valid response **/
		void ResponseFunc(boolean iSuccessfulSend, TradeGetStockQuoteResult iResponse);
	}

	public class TradeGetStockQuoteResult
	{
		public Trade_StockViewInfoItem	stockQuoteItem;
		public String                      resultCode;
		public String                      errorMessage;
		/**		    
		 * @param iResult - being sent or not
		 * @param iStatusCode - return code from server
		 * @param iBrokerMessage - broker message for successful sent
		 * @param Trade_StockViewInfoItem - information of the request stock item
		 **/			
		public TradeGetStockQuoteResult( String iResultCode, String iErrorMessage, Trade_StockViewInfoItem iStockQuoteItem)
		{
			resultCode   = iResultCode;
			errorMessage = iErrorMessage;
			if (iStockQuoteItem != null)
				stockQuoteItem = new Trade_StockViewInfoItem(iStockQuoteItem);
			else
				stockQuoteItem = null;
		}
	}	
	
	protected final 	 boolean debugMode = false;
	protected String                          urlString;
	protected String                          urlPort;
	private boolean					demoData	= false;
	private   String                         requestCode = null;
	private ITradeGetStockQuoteResponse	responseHandler;
	
	private final int trialMax          = 2;
	protected final int SOCKET_TIMEOUT	 = 20000;
	protected final int CONNECT_TIMEOUT = 20000;
	protected Context					callerContext;
	
	private final int waitNextTrial    = 500;	
	
	/** Request for a stock quite information.  Function call requires a caller **/
	public TradeGetDetailStockQuote(Context iContext)
	{
		callerContext = iContext;
		urlString     = null;
	}

	public void Dispose()
	{		
		messageHandler = null;
		urlString      = null;
		if (debugMode)
			TDStockLog.i(LOG_TAG, "We have no reference anymore");	
	}
	
	/** Place in the quote number that you are looking for **/
	public void SetRequestQuoteInfo(boolean iIsDevelopment, String iQuoteNumber, String iLogonAccount, String iLogonToken)
	{
		if ((iQuoteNumber == null) || (iLogonAccount == null) || (iLogonToken == null))
			urlString = null;
		else
			urlString = TradeAppInfo.GetDetailStockCodeURL(iIsDevelopment, iQuoteNumber, iLogonAccount, iLogonToken);
	
		requestCode = iQuoteNumber;
		urlPort = TradeAppInfo.GetStockCodePort();
	}

	// Demo Data
	private Trade_StockViewInfoItem GetDemoQuote()
	{
		Trade_StockViewInfoItem quoteItem;

		TDStockLog.i(LOG_TAG, "Using Prepared Data");
		quoteItem = new Trade_StockViewInfoItem(requestCode, "示範", "Demo");
		quoteItem.SetStartPrice("868.5", false);
		quoteItem.SetPriceInfo("883.5", "883.0", "883.5", true);
		quoteItem.SetStepVolume("400");
		quoteItem.SetSpreadPrice("0.5");
		quoteItem.SetCurrencyCode("HKD");
		return quoteItem;
	}
	
	private final int	REQUEST_DATA_SENT_FAIL		= 0;
	private final int	REQUEST_DATA_SENT_SUCCESS	= 1;	
	
	private Handler messageHandler = new Handler()
	{
		@Override
		public void handleMessage(Message msg)
		{
			if (responseHandler == null)
				return;
							
			switch (msg.what)
			{
				case REQUEST_DATA_SENT_FAIL:
					responseHandler.ResponseFunc(false, null);
					break;
				case REQUEST_DATA_SENT_SUCCESS:
					responseHandler.ResponseFunc(true, (TradeGetStockQuoteResult)msg.obj);
					break;
			}
		}
	};	
	
	public void returnResultWithHandler(boolean iSendSuccess, TradeGetStockQuoteResult iResult)
	{		
		if (messageHandler == null)
			return;
					
		Message msg;

		// Provide success or fail reply
		msg = new Message();
		if (!iSendSuccess)
			msg.what = REQUEST_DATA_SENT_FAIL;
		else
		{
			msg.what = REQUEST_DATA_SENT_SUCCESS;
			msg.obj = iResult;
		}
		messageHandler.sendMessage(msg);
	}
	
	public void SendRequest(boolean iDemoData, ITradeGetStockQuoteResponse iResponse)
	{
		demoData        = iDemoData;
		responseHandler = iResponse;
	
		Thread internalThreadObj;		
		internalThreadObj = new Thread()
		{
			@Override
			public void run()
			{				
				//This is even faster
				if (demoData)
				{
					try
					{
						Thread.sleep(Trade_AppConstant.demoHoldTime);
					}
					catch (InterruptedException e)
					{
						e.printStackTrace();
						TDStockLog.e(LOG_TAG, "SendData=>Exception: " + e.toString());
					}
					returnResultWithHandler(true, new TradeGetStockQuoteResult("0", "", GetDemoQuote()));					
					return;
				}
				
				if (!DeviceInfo.IsNetworkAvailable(callerContext) || (urlString == null))
				{
					returnResultWithHandler(false, new TradeGetStockQuoteResult("", "", null));
					return;
				}
			
				int   				trialCount;
				TradeGetStockQuoteResult result;
				HttpClient 			client;
				HttpGet    			request;
				HttpParams 			modParams;

				if (debugMode)
					TDStockLog.i(LOG_TAG, "SendDataSub=>Request: " + urlString);
						
				client = new DefaultHttpClient();
				request = new HttpGet(urlString);
				modParams = request.getParams();

				// Change the setting
				HttpConnectionParams.setSoTimeout(modParams, SOCKET_TIMEOUT);
				HttpConnectionParams.setConnectionTimeout(modParams, CONNECT_TIMEOUT);
				request.setParams(modParams);			
				
				trialCount = 0;
				while(true)
				{
					result = SendDataSub( client, request );
					//If we did not get the require login information
					if (result == null)
					{
						++trialCount;
						if (trialCount < trialMax)
						{
							if (debugMode)
								TDStockLog.i(LOG_TAG, "SendRequest: Retry performed: " + trialCount);
							try
							{
								sleep(waitNextTrial);
							}
							catch(Exception ex)
							{
								TDStockLog.e(LOG_TAG, "SendRequest: Ex=" + ex.toString());
							}
							continue;
						}
					}
					break;
				}	
				
				if (result == null)
					result = new TradeGetStockQuoteResult("", "", new Trade_StockViewInfoItem("", "", ""));
				
				//Report to the caller
				returnResultWithHandler(true, result);					
			}
		};		
		internalThreadObj.setName(LOG_TAG);		
		internalThreadObj.start();
	}		
		
	
	protected TradeGetStockQuoteResult SendDataSub(HttpClient iClient, HttpGet iRequest)
	{
		String 	 stockCode, chnName, engName, nominal;
		String 	 bidPrice, askPrice, lotSize;
		String 	 currencyCode;
		String     prevClosePrice;
		String     statusMsg, descriptMessage;
		String     tmpString;
		Trade_StockViewInfoItem  stockInfo;
		
		stockInfo  = null;		
		statusMsg = "";
		descriptMessage = "";
		stockCode = "";
		chnName = ""; 
		engName = "";
		nominal = "";
		bidPrice = "";		
		askPrice 	   = "";
		lotSize      = "";
		prevClosePrice = "";
		currencyCode = "";	
//		isSuspended   = false;
		try
		{
			HttpResponse webResponse;
			StringBuffer contentString;					

			webResponse = iClient.execute(iRequest);
			
			contentString = CommunicTools.GetWebResponseInStringBuffer(webResponse);										
			
			statusMsg = CommunicTools.FindXMLStringContent(contentString, "Status");
			descriptMessage = CommunicTools.FindXMLStringContent(contentString, "ErrorMessage");
			stockCode = CommunicTools.FindXMLStringContent(contentString, "STOCK_CODE");
			chnName = CommunicTools.FindXMLStringContent(contentString, "SCHI_NAME");
			chnName = chnName.trim();
			engName = CommunicTools.FindXMLStringContent(contentString, "SENG_NAME");
			engName = engName.trim();
			nominal = CommunicTools.FindXMLStringContent(contentString, "NOMINAL");
			bidPrice = CommunicTools.FindXMLStringContent(contentString, "BID_PRICE");
			askPrice = CommunicTools.FindXMLStringContent(contentString, "ASK_PRICE");
			lotSize = CommunicTools.FindXMLStringContent(contentString, "LOT_SIZE");
//			netChange = CommunicTools.FindXMLStringContent(contentString, "NET");
			currencyCode = CommunicTools.FindXMLStringContent(contentString, "CURRENCY_CODE");
			prevClosePrice  = CommunicTools.FindXMLStringContent(contentString, "PREV_CLOSE_PRICE");
			
//			tmpString = CommunicTools.FindXMLStringContent(contentString, "SUSP_STOCK");
//			if (tmpString.equals("Y"))
//				isSuspended = true;
			
			tmpString = stockCode;
			if (tmpString.equals("") == false)
				tmpString = Trade_StockFunctionTools.FormatFullStockCode(tmpString);
			
			stockInfo = new Trade_StockViewInfoItem(tmpString, chnName, engName);
			stockInfo.SetStartPrice(prevClosePrice, false);
			stockInfo.SetPriceInfo(nominal, bidPrice, askPrice, true);
			
			stockInfo.SetStepVolume(lotSize);								
			stockInfo.SetCurrencyCode(currencyCode);			
			//Calculate the spread price
			tmpString = Trade_StockFunctionTools.GetStockPriceSpread(stockInfo.GetCurPriceText());
			stockInfo.SetSpreadPrice(tmpString);	

			//Custom set the error to -2 not to conflict with the -1 (Session Expired)
			if (statusMsg.equals(""))
			{
				if (stockCode.equals(""))
				{
					statusMsg = "-2";
					if (descriptMessage.equals(""))
						descriptMessage = callerContext.getResources().getString(R.string.StockNotFound_Text);
				}
				else
					statusMsg = "0";
			}
			
			if (debugMode)
				TDStockLog.i(LOG_TAG, "SendDataSub: Status=" + statusMsg);
		}
		catch (ClientProtocolException e)
		{
			e.printStackTrace();
			TDStockLog.e(LOG_TAG, "SendDataSub=>ClientProtocolException: " + e.toString());
			return null;
		}
		catch (IOException e)
		{
			e.printStackTrace();			
			TDStockLog.e(LOG_TAG, "SendDataSub=>IOException: " + e.toString());
			return null;
		}
		catch (Exception e)
		{
			e.printStackTrace();			
			TDStockLog.e(LOG_TAG, "SendDataSub=>Exception: " + e.toString());
			return null;
		}
		
		return new TradeGetStockQuoteResult(statusMsg, descriptMessage, stockInfo); 		
	}	
}

